import { ref, nextTick } from 'vue'
import { gsap } from 'gsap'
import type { RouteLocationNormalized } from 'vue-router'

export interface PageTransitionConfig {
  duration?: number
  ease?: string
  direction?: 'horizontal' | 'vertical' | 'fade' | 'scale' | 'rotate'
  stagger?: number
}

export const usePageTransition = () => {
  const isTransitioning = ref(false)
  const transitionProgress = ref(0)

  // 预设动画配置
  const presets = {
    slide: {
      duration: 600,
      ease: 'power2.inOut',
      direction: 'horizontal' as const,
    },
    fade: {
      duration: 400,
      ease: 'power2.out',
      direction: 'fade' as const,
    },
    scale: {
      duration: 500,
      ease: 'back.inOut(1.7)',
      direction: 'scale' as const,
    },
    rotate: {
      duration: 700,
      ease: 'power2.inOut',
      direction: 'rotate' as const,
    },
  }

  // 根据路由确定动画方向
  const getAnimationDirection = (
    from: RouteLocationNormalized,
    to: RouteLocationNormalized
  ): 'forward' | 'backward' => {
    // 定义路由层级
    const routeLevels: { [key: string]: number } = {
      '/': 0,
      '/my_space': 1,
      '/add_picture': 2,
      '/picture': 3,
      '/user/login': 1,
      '/user/register': 1,
      '/admin': 4,
    }

    const fromLevel = routeLevels[from.path] ?? 0
    const toLevel = routeLevels[to.path] ?? 0

    return toLevel > fromLevel ? 'forward' : 'backward'
  }

  // 页面进入动画
  const pageEnter = (
    element: Element,
    config: PageTransitionConfig = presets.slide
  ): Promise<void> => {
    return new Promise((resolve) => {
      isTransitioning.value = true
      transitionProgress.value = 0

      const { duration = 600, ease = 'power2.out', direction = 'horizontal' } = config

      let animation: gsap.core.Timeline

      switch (direction) {
        case 'horizontal':
          animation = gsap.timeline({
            onUpdate: () => {
              transitionProgress.value = animation.progress() * 100
            },
            onComplete: () => {
              isTransitioning.value = false
              resolve()
            },
          })
          animation
            .set(element, { x: '100%', opacity: 0 })
            .to(element, {
              x: '0%',
              opacity: 1,
              duration: duration / 1000,
              ease,
            })
          break

        case 'vertical':
          animation = gsap.timeline({
            onUpdate: () => {
              transitionProgress.value = animation.progress() * 100
            },
            onComplete: () => {
              isTransitioning.value = false
              resolve()
            },
          })
          animation
            .set(element, { y: '50px', opacity: 0 })
            .to(element, {
              y: '0px',
              opacity: 1,
              duration: duration / 1000,
              ease,
            })
          break

        case 'fade':
          animation = gsap.timeline({
            onUpdate: () => {
              transitionProgress.value = animation.progress() * 100
            },
            onComplete: () => {
              isTransitioning.value = false
              resolve()
            },
          })
          animation
            .set(element, { opacity: 0 })
            .to(element, {
              opacity: 1,
              duration: duration / 1000,
              ease,
            })
          break

        case 'scale':
          animation = gsap.timeline({
            onUpdate: () => {
              transitionProgress.value = animation.progress() * 100
            },
            onComplete: () => {
              isTransitioning.value = false
              resolve()
            },
          })
          animation
            .set(element, { scale: 0.8, opacity: 0 })
            .to(element, {
              scale: 1,
              opacity: 1,
              duration: duration / 1000,
              ease,
            })
          break

        case 'rotate':
          animation = gsap.timeline({
            onUpdate: () => {
              transitionProgress.value = animation.progress() * 100
            },
            onComplete: () => {
              isTransitioning.value = false
              resolve()
            },
          })
          animation
            .set(element, { rotation: -10, scale: 0.9, opacity: 0 })
            .to(element, {
              rotation: 0,
              scale: 1,
              opacity: 1,
              duration: duration / 1000,
              ease,
            })
          break

        default:
          isTransitioning.value = false
          resolve()
      }
    })
  }

  // 页面离开动画
  const pageLeave = (
    element: Element,
    config: PageTransitionConfig = presets.slide
  ): Promise<void> => {
    return new Promise((resolve) => {
      isTransitioning.value = true
      transitionProgress.value = 0

      const { duration = 600, ease = 'power2.in', direction = 'horizontal' } = config

      let animation: gsap.core.Timeline

      switch (direction) {
        case 'horizontal':
          animation = gsap.timeline({
            onUpdate: () => {
              transitionProgress.value = animation.progress() * 100
            },
            onComplete: () => {
              isTransitioning.value = false
              resolve()
            },
          })
          animation.to(element, {
            x: '-100%',
            opacity: 0,
            duration: duration / 1000,
            ease,
          })
          break

        case 'vertical':
          animation = gsap.timeline({
            onUpdate: () => {
              transitionProgress.value = animation.progress() * 100
            },
            onComplete: () => {
              isTransitioning.value = false
              resolve()
            },
          })
          animation.to(element, {
            y: '-50px',
            opacity: 0,
            duration: duration / 1000,
            ease,
          })
          break

        case 'fade':
          animation = gsap.timeline({
            onUpdate: () => {
              transitionProgress.value = animation.progress() * 100
            },
            onComplete: () => {
              isTransitioning.value = false
              resolve()
            },
          })
          animation.to(element, {
            opacity: 0,
            duration: duration / 1000,
            ease,
          })
          break

        case 'scale':
          animation = gsap.timeline({
            onUpdate: () => {
              transitionProgress.value = animation.progress() * 100
            },
            onComplete: () => {
              isTransitioning.value = false
              resolve()
            },
          })
          animation.to(element, {
            scale: 0.8,
            opacity: 0,
            duration: duration / 1000,
            ease,
          })
          break

        case 'rotate':
          animation = gsap.timeline({
            onUpdate: () => {
              transitionProgress.value = animation.progress() * 100
            },
            onComplete: () => {
              isTransitioning.value = false
              resolve()
            },
          })
          animation.to(element, {
            rotation: 10,
            scale: 0.9,
            opacity: 0,
            duration: duration / 1000,
            ease,
          })
          break

        default:
          isTransitioning.value = false
          resolve()
      }
    })
  }

  // 元素交错动画
  const staggerElements = (
    elements: NodeListOf<Element> | Element[],
    config: PageTransitionConfig & { stagger?: number } = {}
  ): Promise<void> => {
    return new Promise((resolve) => {
      const { 
        duration = 400, 
        ease = 'power2.out', 
        stagger = 0.1,
        direction = 'fade' 
      } = config

      let baseAnimation: any = {}
      let fromAnimation: any = {}

      switch (direction) {
        case 'horizontal':
          fromAnimation = { x: 30, opacity: 0 }
          baseAnimation = { x: 0, opacity: 1 }
          break
        case 'vertical':
          fromAnimation = { y: 30, opacity: 0 }
          baseAnimation = { y: 0, opacity: 1 }
          break
        case 'scale':
          fromAnimation = { scale: 0.8, opacity: 0 }
          baseAnimation = { scale: 1, opacity: 1 }
          break
        case 'fade':
        default:
          fromAnimation = { opacity: 0 }
          baseAnimation = { opacity: 1 }
          break
      }

      gsap.fromTo(
        elements,
        fromAnimation,
        {
          ...baseAnimation,
          duration: duration / 1000,
          ease,
          stagger,
          onComplete: resolve,
        }
      )
    })
  }

  // 页面滚动到顶部
  const scrollToTop = (smooth = true): Promise<void> => {
    return new Promise((resolve) => {
      if (smooth) {
        gsap.to(window, {
          scrollTo: { y: 0 },
          duration: 0.5,
          ease: 'power2.out',
          onComplete: resolve,
        })
      } else {
        window.scrollTo(0, 0)
        resolve()
      }
    })
  }

  // 创建页面转场效果
  const createPageTransition = (
    type: keyof typeof presets = 'slide'
  ) => {
    const config = presets[type]

    return {
      name: 'page-transition',
      mode: 'out-in' as const,
      onEnter: (el: Element, done: () => void) => {
        pageEnter(el, config).then(done)
      },
      onLeave: (el: Element, done: () => void) => {
        pageLeave(el, config).then(done)
      },
    }
  }

  // 路由级别的过渡动画
  const routeTransition = (
    from: RouteLocationNormalized,
    to: RouteLocationNormalized
  ) => {
    const direction = getAnimationDirection(from, to)
    
    // 根据路由变化选择不同的动画
    if (from.path === to.path) {
      return createPageTransition('fade')
    }
    
    if (direction === 'forward') {
      return createPageTransition('slide')
    } else {
      return createPageTransition('scale')
    }
  }

  return {
    isTransitioning,
    transitionProgress,
    pageEnter,
    pageLeave,
    staggerElements,
    scrollToTop,
    createPageTransition,
    routeTransition,
    getAnimationDirection,
    presets,
  }
}
